<!--
  -    Copyright (c) 2018-2025, cloud All rights reserved.
  -
  - Redistribution and use in source and binary forms, with or without
  - modification, are permitted provided that the following conditions are met:
  -
  - Redistributions of source code must retain the above copyright notice,
  - this list of conditions and the following disclaimer.
  - Redistributions in binary form must reproduce the above copyright
  - notice, this list of conditions and the following disclaimer in the
  - documentation and/or other materials provided with the distribution.
  - Neither the name of the pig4cloud.com developer nor the names of its
  - contributors may be used to endorse or promote products derived from
  - this software without specific prior written permission.
  - Author: cloud
  -->

<template>
  <BasicContainer class="user">
    <ElRow :span="24">
      <ElCol :xs="24" :sm="24" :md="5" class="user__tree">
        <FyTree :option="treeOption" :data="treeData" @node-click="nodeClick">
          <template #default="{ node, data }">
            <span class="el-tree-node__label">
              <ElTooltip v-if="data.isLock" class="item" effect="dark" content="无数据权限" placement="right-start">
                <span>{{ node.label }} <i class="el-icon-lock"></i></span>
              </ElTooltip>
              <span v-if="!data.isLock">{{ node.label }}</span>
            </span>
          </template>
        </FyTree>
      </ElCol>
      <ElCol :xs="24" :sm="24" :md="19" class="user__main">
        <FyCurd
          ref="crud"
          v-model="form"
          :option="option"
          :page.sync="page"
          :table-loading="listLoading"
          :before-open="handleOpenBefore"
          :data="list"
          @on-load="getList"
          @search-change="searchChange"
          @refresh-change="refreshChange"
          @size-change="sizeChange"
          @current-change="currentChange"
          @row-update="update"
          @row-save="create">
          <template #menuLeft>
            <ElButton
              v-if="sys_user_add"
              class="filter-item"
              type="primary"
              size="small"
              icon="el-icon-edit"
              @click="$refs.crud.rowAdd()">
              添加
            </ElButton>
            <ElButton
              class="filter-item"
              plain
              type="primary"
              size="small"
              icon="el-icon-upload"
              @click="$refs.excelUpload.show()">
              导入
            </ElButton>
            <ElButton
              class="filter-item"
              plain
              type="primary"
              size="small"
              icon="el-icon-download"
              @click="exportExcel">
              导出
            </ElButton>
          </template>
          <template #username="scope">
            <span>{{ scope.row.username }}</span>
          </template>
          <template #role="scope">
            <span v-for="(item, index) in scope.row.roleList" :key="index">
              <ElTag>{{ item.roleName }} </ElTag>&nbsp;&nbsp;
            </span>
          </template>
          <template #post="scope">
            <span v-for="(item, index) in scope.row.postList" :key="index">
              <ElTag>{{ item.postName }} </ElTag>&nbsp;&nbsp;
            </span>
          </template>
          <template #deptId="scope">
            {{ scope.row.deptName }}
          </template>
          <template #lockFlag="scope">
            <ElTag>{{ scope.label }}</ElTag>
          </template>
          <template #menu="scope">
            <ElButton
              v-if="sys_user_edit"
              type="text"
              size="small"
              icon="el-icon-edit"
              @click="handleUpdate(scope.row, scope.index)">
              编辑
            </ElButton>
            <ElButton v-if="sys_user_edit" type="text" size="small" icon="el-icon-edit" @click="editDetails(scope.row)">
              编辑详细信息
            </ElButton>
            <ElButton
              v-if="sys_user_del"
              type="text"
              size="small"
              icon="el-icon-delete"
              @click="deletes(scope.row, scope.index)">
              删除
            </ElButton>
          </template>
          <template #deptIdForm>
            <FyInputTree
              v-model="form.deptId"
              :node-click="getNodeData"
              :dic="treeDeptData"
              :props="defaultProps"
              placeholder="请选择所属部门" />
          </template>
          <template #roleForm>
            <FySelect v-model="role" :dic="rolesOptions" :props="roleProps" multiple placeholder="请选择角色" />
          </template>
          <template #postForm>
            <FySelect v-model="post" multiple placeholder="请选择岗位" :dic="postOptions" :props="postProps" />
          </template>
        </FyCurd>
      </ElCol>
      <!--excel 模板导入 -->
      <ExcelUpload
        ref="excelUpload"
        title="用户信息导入"
        url="/admin/user/import"
        temp-url="/admin/sys-file/local/file/user.xlsx"
        @refreshDataList="refreshChange" />
    </ElRow>
    <!-- 弹窗, 新增 / 修改 -->
    <UserDetailForm v-if="addOrUpdateVisible" ref="userDetailForm" />
  </BasicContainer>
</template>

<script>
  import { listPosts } from '@/api/admin/post'
  import { addObj, delObj, fetchList, putObj } from '@/api/admin/user'
  import { deptRoleList } from '@/api/admin/role'
  import { fetchTree } from '@/api/admin/dept'
  import { tableOption } from '@/const/crud/admin/user'
  import { mapState } from 'vuex'

  import UserDetailForm from '@/module/admin/userinfo/userinfoDialog'
  import { services } from '@/config'

  export default {
    name: 'SysUser',
    components: {
      UserDetailForm
    },
    data() {
      return {
        searchForm: {},
        treeOption: {
          nodeKey: 'id',
          addBtn: false,
          menu: false,
          props: {
            label: 'name',
            value: 'id'
          }
        },
        treeData: [],
        option: tableOption,
        treeDeptData: [],
        roleProps: {
          label: 'roleName',
          value: 'roleId'
        },
        postProps: {
          label: 'postName',
          value: 'postId'
        },
        defaultProps: {
          label: 'name',
          value: 'id'
        },
        page: {
          total: 0, // 总页数
          currentPage: 1, // 当前页数
          pageSize: 20, // 每页显示多少条,
          isAsc: false // 是否倒序
        },
        list: [],
        listLoading: true,
        role: [],
        post: [],
        form: {},
        rolesOptions: [],
        postOptions: [],
        addOrUpdateVisible: false
      }
    },
    computed: {
      ...mapState('user', ['permissions'])
    },
    watch: {
      role() {
        this.form.role = this.role
      },
      post() {
        this.form.post = this.post
      }
    },
    created() {
      this.sys_user_add = this.permissions.sys_user_add
      this.sys_user_edit = this.permissions.sys_user_edit
      this.sys_user_del = this.permissions.sys_user_del
      this.init()
    },
    methods: {
      init() {
        fetchTree().then(response => {
          this.treeData = response.data.data
        })
      },
      nodeClick(data) {
        this.page.page = 1
        this.getList(this.page, { deptId: data.id })
      },
      getList(page, params) {
        this.listLoading = true
        fetchList(
          Object.assign(
            {
              current: page.currentPage,
              size: page.pageSize
            },
            params,
            this.searchForm
          )
        ).then(response => {
          this.list = response.data.data.records
          this.page.total = response.data.data.total
          this.listLoading = false
        })
      },
      getNodeData() {
        deptRoleList().then(response => {
          this.rolesOptions = response.data.data
        })
        listPosts().then(response => {
          this.postOptions = response.data.data
        })
      },
      searchChange(param, done) {
        this.searchForm = param
        this.page.currentPage = 1
        this.getList(this.page, param)
        done()
      },
      sizeChange(pageSize) {
        this.page.pageSize = pageSize
      },
      currentChange(current) {
        this.page.currentPage = current
      },
      refreshChange() {
        this.getList(this.page)
      },
      handleOpenBefore(show, type) {
        window.boxType = type
        // 查询部门树
        fetchTree().then(response => {
          this.treeDeptData = response.data.data
        })
        // 查询角色列表
        deptRoleList().then(response => {
          this.rolesOptions = response.data.data
        })
        // 查询岗位列表
        listPosts().then(response => {
          this.postOptions = response.data.data
        })

        if (['edit', 'view'].includes(type)) {
          this.$set(this.form, 'postList', this.form.postList || [])
          this.$set(this.form, 'roleList', this.form.roleList || [])
          this.role = []
          for (let i = 0; i < this.form.roleList.length; i++) {
            this.role[i] = this.form.roleList[i].roleId
          }
          this.post = []
          for (let i = 0; i < this.form.postList.length; i++) {
            this.post[i] = this.form.postList[i].postId
          }
        } else if (type === 'add') {
          this.role = []
          this.post = []
          this.form.username = undefined
          this.form.phone = undefined
          this.form.password = undefined
        }
        show()
      },
      handleUpdate(row, index) {
        this.$refs.crud.rowEdit(row, index)
        this.form.password = '******'
      },
      create(row, done, loading) {
        if (this.form.phone && this.form.phone.indexOf('*') > 0) {
          this.form.phone = undefined
        }
        addObj(this.form)
          .then(() => {
            this.getList(this.page)
            done()
            this.$notify.success('创建成功')
          })
          .catch(() => {
            loading()
          })
      },
      update(row, index, done, loading) {
        if (this.form.phone && this.form.phone.indexOf('*') >= 0) {
          this.form.phone = undefined
        }
        if (this.form.password && this.form.password.indexOf('******') >= 0) {
          this.form.password = undefined
        }
        putObj(this.form)
          .then(() => {
            this.getList(this.page)
            done()
            this.$notify.success('修改成功')
          })
          .catch(() => {
            loading()
          })
      },
      deletes(row, index) {
        this.$confirm(`此操作将永久删除该用户(用户名:${row.username}), 是否继续?`, '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          delObj(row.userId)
            .then(() => {
              this.list.splice(index, 1)
              this.$notify.success('删除成功')
            })
            .catch(() => {
              this.$notify.error('删除失败')
            })
        })
      },
      exportExcel() {
        this.$downBlobFile(`${services.adminService}user/export`, this.searchForm, 'user.xlsx')
      },
      async editDetails(row) {
        this.addOrUpdateVisible = true
        await this.$nextTick()
        await this.$refs.userDetailForm.init(row.userInfoId, row.userId, row.username)
      }
    }
  }
</script>

<style lang="scss">
  .user {
    &__tree {
      padding-top: 3px;
      padding-right: 20px;
    }

    &__main {
      .el-card__body {
        padding-top: 0;
      }
    }
  }
</style>
